package org.opennaas.core.persistence; import java.io.Serializable; import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; /** * GenericJPARepository that gets the EntityManagerFactory from the OSGi registry * * @author eduardgrasa * * @param <T> * @param <ID> */ public class GenericOSGiJpaRepository<T, ID extends Serializable> extends GenericJpaRepository<T, ID> { private EntityManagerFactory entityManagerFactory = null; private String persistenceUnit = null; private static Log logger = LogFactory.getLog(GenericOSGiJpaRepository.class); public GenericOSGiJpaRepository() { super(); } public void setPersistenceUnit(String persistenceUnit) { this.persistenceUnit = persistenceUnit; } public void initializeEntityManager() throws Exception { try { /* * FIXME We have to find a better method to do this to get the entityManager. It tries 10 times to try to get the persistence. The * persistence bundle spends more time because it is to need the config file persistence.xml which it needs more time to finish it. */ entityManagerFactory = waitForEntityManager(persistenceUnit); if (entityManagerFactory == null) throw new PersistenceException(); logger.debug("DESCRIPTION. Entity manager: " + entityManagerFactory); } catch (PersistenceException e) { logger.debug("PersistenceException: " + e.getMessage()); throw new Exception(e); } setEntityManager(entityManagerFactory.createEntityManager()); } public void close() { EntityManager entityManager = getEntityManager(); if (entityManager != null) { logger.debug("Closing entity manager: " + entityManager); entityManager.close(); setEntityManager(null); } } private EntityManagerFactory getEntityManagerFactoryFromOSGiRegistry(String persistenceUnit) { EntityManagerFactory entityManagerFactory = null; Filter filter = null; try { filter = createServiceFilter(EntityManagerFactory.class .getName(), createFilterProperties(persistenceUnit)); } catch (InvalidSyntaxException e) { e.printStackTrace(); logger.error("InvalidSyntaxException:" + e.getMessage()); return null; } try { entityManagerFactory = (EntityManagerFactory) getServiceFromRegistry( Activator.getBundleContext(), filter); } catch (InterruptedException e) { e.printStackTrace(); logger.error("InterruptedException:" + e.getMessage()); } return entityManagerFactory; } public EntityManagerFactory waitForEntityManager(String persistenceUnit) { int MAX_RETRIES = 10; boolean active = false; for (int i = 0; i < MAX_RETRIES; i++) { EntityManagerFactory entityManagerFactory = getEntityManagerFactoryFromOSGiRegistry(persistenceUnit); active = (null != entityManagerFactory); if (active == true) { return entityManagerFactory; } logger.info("Waiting for the activation of Entity Manager"); try { Thread.sleep(1000); } catch (InterruptedException ex) { ex.printStackTrace(); } } return null; } private Properties createFilterProperties(String persistenceUnit) { Properties properties = new Properties(); properties.setProperty("osgi.unit.name", persistenceUnit); properties.setProperty("org.apache.aries.jpa.container.managed", "true"); return properties; } private Filter createServiceFilter(String clazz, Properties properties) throws InvalidSyntaxException { StringBuilder query = new StringBuilder(); query.append("(&"); query.append("(").append(Constants.OBJECTCLASS).append("=").append(clazz).append(")"); for (String key : properties.stringPropertyNames()) { String value = properties.getProperty(key); query.append("(").append(key).append("=").append(value).append(")"); } query.append(")"); return FrameworkUtil.createFilter(query.toString()); } private Object getServiceFromRegistry(BundleContext bundleContext, Filter filter) throws InterruptedException { ServiceTracker tracker = new ServiceTracker(bundleContext, filter, null); tracker.open(); Object service = null; logger.debug("Looking up Service from registry with properties: " + filter); service = tracker.waitForService(10000); tracker.close(); if (service != null) { return service; } return null; } }